﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static WindowsFormsApp1.IICMoudle.UpgradeResult;

namespace WindowsFormsApp1.IICMoudle
{
    class ChipAw : IChip
    {

        private static readonly int REWRITE_TIMES = I2CConstant.REWRITE_TIMES;
        private const int WriteBufLen = 64;

        public IICDataListener Listener { get; set; }

        public bool WriteReg(byte[] writeData, int writeLen)
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];
            uint wLen;
            uint rLen;

            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;

            for (int i = 1; i <= writeLen; i++)
            {
                wBuf[i] = writeData[i - 1];
            }
            wLen = (uint)(writeLen + 1);
            rLen = 0;
            return IIC.WriteRead(wLen, wBuf, rLen, rBuf);
        }

        public byte[] ReadReg(byte[] readData, int readLen)
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];
            uint wLen;
            uint rLen;

            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;

            for (int i = 1; i <= readData.Length; i++)
            {
                wBuf[i] = readData[i - 1];
            }
            wLen = (uint)(readData.Length + 1);
            rLen = (uint)readLen;
            IIC.WriteRead(wLen, wBuf, rLen, rBuf);

            byte[] result = new byte[readLen];
            Array.Copy(rBuf, 0, result, 0, readLen);

            return result;
        }

        public void SetDebugMode(byte mode)
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];

            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_MODE_A;
            wBuf[2] = mode;
            IIC.WriteRead(3, wBuf, 0, rBuf);
        }

        public void ClearDataReady()
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];

            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DATA_READY_A;
            wBuf[2] = (byte)ChipAwConstance.DataReady.DATA_READY_CLEAR;
            IIC.WriteRead(3, wBuf, 0, rBuf);
        }

        public int[] GetData(int len)
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];

            if (len % 2 != 0)
            {
                return null;
            }

            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_DATA_A;

            if (IIC.WriteRead(2, wBuf, (uint)len, rBuf))
            {
                short checkSum1 = (short)((rBuf[len - 1] << 8) & 0xFF00 | (rBuf[len - 2] & 0xFF));
                short checkSum2 = Utils.CheckSumTwoBytes(rBuf, 0, len - 2);

                if (checkSum1 == checkSum2)
                {
                    int[] data = new int[len / 2];
                    for (int i = 0; i < len / 2; i++)
                    {
                        data[i] = (short)(rBuf[i * 2 + 1] << 8 | rBuf[i * 2]);
                    }

                    return data;
                    //if (!Utils.CheckIsAllZero(data))
                    //{
                    //    return data;
                    //}
                }
            }
            return null;
        }

        public int ReadDataReady()
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];

            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DATA_READY_A;

            if (IIC.WriteRead(2, wBuf, 1, rBuf))
            {
                return rBuf[0];
            }
            else
            {
                return -1;
            }
        }

        public string ReadFwVersion()
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];

            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_FW_VERSION;
            uint rLen = 4;
            uint wLen = 2;

            int cnt = 0;

            while (cnt <= REWRITE_TIMES)
            {
                if (IIC.WriteRead(wLen, wBuf, rLen, rBuf))
                {
                    //Console.WriteLine(rBuf[0] + "," + rBuf[1] + "," + rBuf[2] + "," + rBuf[3]);
                    if (!Utils.CheckIsAllZero(rBuf, (int)rLen))
                    {
                        return string.Format("v{0}.{1}.{2}.{3}",
                            rBuf[0].ToString(),
                            rBuf[1].ToString(),
                            rBuf[2].ToString(),
                            rBuf[3].ToString());
                    }
                }
                cnt++;
                Sleep(100);
            }

            return "-1, error";
        }

        public short ReadModuleConnect()
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];

            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_MODULE_CONN_STATUS_STATIC;
            uint rLen = 4;
            uint wLen = 2;

            int cnt = 0;

            while (cnt <= REWRITE_TIMES)
            {
                if (IIC.WriteRead(wLen, wBuf, rLen, rBuf))
                {
                    return (short)((rBuf[1] << 8) & 0xFF00 | (rBuf[0] & 0xFF));
                }
                cnt++;
                Sleep(100);
            }

            return 0xFF;
        }

        public string ReadModuleConnectDynamic()
        {
            string connStatus = "11111111";

            SetDebugMode(0x00);
            ClearDataReady();
            Utils.Sleep(10);
            SetDebugMode((byte)ChipAwConstance.Reg.REG_MODULE_CONN_STATUS);
            Utils.Sleep(20);
            int cnt = ReadDataReady();
            //Console.WriteLine("cnt = " + cnt);

            int i = 0;
            while (i++ < REWRITE_TIMES * 3 && cnt <= 2)
            {
                Utils.Sleep(50);
                cnt = ReadDataReady();
                Console.WriteLine("read module connect: times = " + i + ", cnt = " + cnt);
            }

            if (cnt > 2)
            {
                int[] data = GetData(cnt);
                if (null != data)
                {
                    connStatus = Convert.ToString((byte)data[0], 2);
                }
            }

            SetDebugMode(0x00);
            ClearDataReady();

            return connStatus;
        }

        public byte[] ReadAfeGain()
        {
            return ReadReg(new byte[] { (byte)ChipAwConstance.Reg.REG_AFE_GAIN }, 2);
        }

        public short[] ReadOffset(int chNum)
        {
            short[] offset = new short[chNum];
            byte[] data = ReadReg(new byte[] { (byte)ChipAwConstance.Reg.REG_OFFSET }, chNum * 2);
            for (int i = 0; i < chNum; i++)
            {
                offset[i] = (short)(data[i * 2 + 1] << 8 | data[i * 2]); ;
            }
            return offset;
        }

        public short ReadDacToMvCoef()
        {
            byte[] data = ReadReg(new byte[] { (byte)ChipAwConstance.Reg.REG_DAC_TO_MV }, 2);
            return (short)(((data[1] << 8) & 0xFF00 | (data[0] & 0xFF)));
        }

        public int ReadAdcToUvCoef()
        {
            byte[] data = ReadReg(new byte[] { (byte)ChipAwConstance.Reg.REG_ADC_TO_UV }, 3);
            return ((data[2] << 16) & 0xFFFF00 | (data[1] << 8) & 0xFF00 | (data[0] & 0xFF));
        }

        public byte WriteCoeff(float[] coefficients)
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];
            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;

            // FB w 00
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_MODE_D;
            wBuf[2] = 0x00;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step1 FB w 00");

            // FC w 00
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DATA_READY_D;
            wBuf[2] = 0x00;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step2 FC w 00");

            int writeLen = 4 * coefficients.Length + 2;

            // FB w 0x30
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_MODE_D;
            wBuf[2] = (byte)ChipAwConstance.Reg.REG_WRITE_COEFF;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step3 FB w 30");

            // FD w data
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_DATA_D;
            // coef * 1000
            for (int i = 0; i < coefficients.Length; i++)
            {
                int coef = (int)(Math.Round(coefficients[i], 3) * 1000);
                wBuf[i * 4 + 2] = (byte)coef;
                wBuf[i * 4 + 3] = (byte)(coef >> 8);
                wBuf[i * 4 + 4] = (byte)(coef >> 16);
                wBuf[i * 4 + 5] = (byte)(coef >> 24);
            }
            // checksum
            byte[] checkBuf = new byte[writeLen - 2];
            Array.Copy(wBuf, 2, checkBuf, 0, checkBuf.Length);
            short checkSum = Utils.CheckSumTwoBytes(checkBuf, 0, writeLen - 2);
            wBuf[writeLen] = (byte)checkSum;
            wBuf[writeLen + 1] = (byte)(checkSum >> 8);
            IIC.WriteRead((uint)(writeLen + 2), wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step4 FD w data: " + Utils.ArrayToHexStr(wBuf, writeLen + 2));

            // FC w data_len
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DATA_READY_D;
            wBuf[2] = (byte)writeLen;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step5 FC w data_len: " + writeLen.ToString("X2"));

            // 0xFC r data_ready
            byte dataReady = (byte)writeLen;
            int cnt = 10;
            while (cnt-- > 0)
            {
                wBuf[1] = (byte)ChipAwConstance.Reg.REG_DATA_READY_D;
                IIC.WriteRead(2, wBuf, 1, rBuf);
                dataReady = rBuf[0];
                if (dataReady == 0x01)
                {
                    break;
                }
                else
                {
                    Utils.Sleep(20);
                }
            }
            Listener.OnIICDataCallBack("step6 FC r data_ready: " + dataReady.ToString("X2"));

            byte value = dataReady;

            // FD r return_code
            if (dataReady == 1)
            {
                wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_DATA_D;
                IIC.WriteRead(2, wBuf, 1, rBuf);
                value = rBuf[0];
                Listener.OnIICDataCallBack("step7 FD r return_code: " + value.ToString("X2"));
            }

            // FB w 00
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_MODE_D;
            wBuf[2] = 0x00;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step8 FB w 00");

            // FC w 00
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DATA_READY_D;
            wBuf[2] = 0x00;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step9 FC w 00");

            return value;
        }

        public float[] ReadCoeff(int chNum)
        {
            float[] coefs = null;

            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];
            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;

            // FB w 00
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_MODE_D;
            wBuf[2] = 0x00;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step1 FB w 00");

            // FC w 00
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DATA_READY_D;
            wBuf[2] = 0x00;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step2 FC w 00");

            // FB w 0x30
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_MODE_D;
            wBuf[2] = (byte)ChipAwConstance.Reg.REG_READ_COEFF;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step3 FB w 31");

            // 0xFC r data_ready
            byte dataReady = 1;
            int cnt = 10;
            while (cnt-- > 0)
            {
                wBuf[1] = (byte)ChipAwConstance.Reg.REG_DATA_READY_D;
                IIC.WriteRead(2, wBuf, 1, rBuf);
                dataReady = (byte)(rBuf[0] & 0xff);
                if (dataReady == (chNum * 4 + 2))
                {
                    break;
                }
                else
                {
                    Utils.Sleep(20);
                }
            }
            Listener.OnIICDataCallBack("step4 FC r data_ready: " + dataReady.ToString("X2"));

            if (dataReady == ((chNum * 4 + 2)))
            {
                // FD r data
                int len = dataReady;
                wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_DATA_D;
                IIC.WriteRead(2, wBuf, (uint)len, rBuf);
                Listener.OnIICDataCallBack("step5 FD r data: " + Utils.ArrayToHexStr(rBuf, len));

                short checkSum1 = (short)((rBuf[len - 1] << 8) & 0xFF00 | (rBuf[len - 2] & 0xFF));
                short checkSum2 = Utils.CheckSumTwoBytes(rBuf, 0, len - 2);

                if (checkSum1 == checkSum2)
                {
                    coefs = new float[chNum];
                    for (int i = 0; i < chNum; i++)
                    {
                        int tmp = (rBuf[i * 4 + 3] << 24 | rBuf[i * 4 + 2] << 16
                            | rBuf[i * 4 + 1] << 8 | rBuf[i * 4]);
                        coefs[i] = (float)Math.Round(tmp / 1000.0, 3);
                    }
                }
                else
                {
                    Listener.OnIICDataCallBack("error: checksum error");
                }
            }

            // FB w 00
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DEBUG_MODE_D;
            wBuf[2] = 0x00;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step6 FB w 00");

            // FC w 00
            wBuf[1] = (byte)ChipAwConstance.Reg.REG_DATA_READY_D;
            wBuf[2] = 0x00;
            IIC.WriteRead(3, wBuf, 0, rBuf);
            Listener.OnIICDataCallBack("step7 FC w 00");

            return coefs;
        }

        public UpgradeResult UpdateFW(string filePath)
        {
            UpgradeResult result = new UpgradeResult();

            // 文件路径为空
            if (string.IsNullOrEmpty(filePath))
            {
                result.result = false;
                result.returnCode = StatusCode.ERRO_FILE_PATH;
                return result;
            }

            // 文件类型不对
            string fileExt = Path.GetExtension(filePath);
            if (fileExt.Equals(".nfw") || fileExt.Equals(".bin"))
            {
                Console.WriteLine("file type ok");
            }
            else
            {
                result.result = false;
                result.returnCode = StatusCode.ERROR_FILE_TYPE;
                return result;
            }

            // 加载固件文件
            byte[] fwData = LoadFile(filePath);

            if (null == fwData)
            {
                result.result = false;
                result.returnCode = StatusCode.ERROR_UPGRADE_FAIL;
                return result;
            }

            // EnterHighSpeed
            IIC.SetIICSpeed((int)I2CConstant.IICSpeed.SPEED_100KHZ);

            // VbatPowerOff 1000ms
            IOoperation.VBRTOFF(1000);

            // KeepInBootCmd
            int j = 0;
            while (j < 20)
            {
                KeepInBootCmd();
                j++;
            }
            Sleep(10);

            // ConnectCmd
            ConnectCmd();
            Sleep(20);

            // EreaseChipCmd
            EreaseChipCmd(fwData.Length);
            Sleep(50);

            // write
            WriteFw(fwData);
            Sleep(200);

            // JumpToApCmd
            JumpToApCmd();

            // ReadBuf
            ReadBuf();
            Sleep(50);

            // ConnectCmd
            ConnectCmd();

            result.result = true;
            result.returnCode = StatusCode.SUCCESS;

            return result;
        }

        private void ReadBuf()
        {
            // 0x5C r 10bytes
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];
            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = 0x5C;

            IIC.WriteRead(2, wBuf, 10, rBuf);
        }

        private void JumpToApCmd()
        {
            // 0xAD w header
            byte[] header = { 0x01, 0x81, 0x04, 0x11, 0x04, 0x00, 0x01, 0x11, 0x00, 0x10, 0x00, 0x01 };
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];
            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = 0xAD;
            Array.Copy(header, 0, wBuf, 2, header.Length);

            IIC.WriteRead((uint)(header.Length + 2), wBuf, 0, rBuf);
        }

        private void WriteFw(byte[] data)
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];
            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;

            int fwLen = data.Length;
            ushort index = 0;
            byte[] w_buf = new byte[WriteBufLen + 12];
            byte head;
            byte[] header = { 0x01, 0x81, 0x03, 0x01, 0x44, 0x00, 0x01, 0xba, 0x00, 0x10, 0x00, 0x01 };
            UInt32 start_addr = 0x01001000;
            Array.Copy(header, 0, w_buf, 0, header.Length);

            while (index < fwLen)
            {
                ////last frame
                //if (index + WriteBufLen >= fwLen)
                //{
                //    w_buf[4] = 0x18;
                //}

                Array.Copy(data, index, w_buf, 12, WriteBufLen);

                w_buf[11] = (byte)((start_addr >> 24) & 0xff);
                w_buf[10] = (byte)((start_addr >> 16) & 0xff);
                w_buf[9] = (byte)((start_addr >> 8) & 0xff);
                w_buf[8] = (byte)((start_addr >> 0) & 0xff);

                UInt16 checksum = 0;
                for (int j = 8; j < w_buf.Length; j++)
                {
                    checksum += w_buf[j];
                }
                w_buf[7] = (byte)checksum;

                checksum = 0;
                for (int j = 0; j < 8; j++)
                {
                    checksum += w_buf[j];
                }
                head = (byte)checksum;

                wBuf[1] = head;

                Array.Copy(w_buf, 0, wBuf, 2, w_buf.Length);

                IIC.WriteRead((uint)(w_buf.Length + 2), wBuf, 0, rBuf);

                index += WriteBufLen;
                start_addr += WriteBufLen;

                Sleep(20);
            }
        }

        private void EreaseChipCmd(int length)
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];
            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;

            byte[] EreaseCmd = { 0x01, 0x81, 0x03, 0x21, 0x06, 0x00, 0x01, 0x25, 0x14, 0x00, 0x00, 0x10, 0x00, 0x01 };
            int secter_need_erease = length / 512 + 1;
            int div = secter_need_erease / 20;
            int rem = secter_need_erease % 20;
            UInt32 start_addr = 0x01001000;
            int sub_sec_num = 0x14;
            EreaseCmd[8] = (byte)sub_sec_num;
            byte head;
            if (rem != 0)
            {
                div++;
            }

            for (int i = 0; i < div; i++)
            {
                if (rem != 0 && i == div - 1)
                {
                    EreaseCmd[8] = (byte)rem;
                }

                EreaseCmd[13] = (byte)((start_addr >> 24) & 0xff);
                EreaseCmd[12] = (byte)((start_addr >> 16) & 0xff);
                EreaseCmd[11] = (byte)((start_addr >> 8) & 0xff);
                EreaseCmd[10] = (byte)((start_addr >> 0) & 0xff);

                UInt16 checksum = 0;
                for (int j = 0; j < 6; j++)
                {
                    checksum += EreaseCmd[8 + j];
                }
                EreaseCmd[7] = (byte)checksum;

                checksum = 0;
                for (int j = 0; j < 8; j++)
                {
                    checksum += EreaseCmd[j];
                }
                head = (byte)checksum;

                wBuf[1] = head;
                Array.Copy(EreaseCmd, 0, wBuf, 2, EreaseCmd.Length);
                IIC.WriteRead((uint)(EreaseCmd.Length + 2), wBuf, 0, rBuf);

                start_addr += 0x2800;

                Sleep(300);
            }

            Sleep(10);
        }

        private void ConnectCmd()
        {
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];

            byte[] header = { 0x01, 0x81, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00 };
            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = 0x85;
            Array.Copy(header, 0, wBuf, 2, header.Length);
            IIC.WriteRead((uint)(2 + header.Length), wBuf, 0, rBuf);

            int k = 1000000;
            while (k-- > 0) ;

            wBuf = new byte[256];
            wBuf[1] = 0xB9;
            IIC.WriteRead(1, wBuf, 14, rBuf);

            wBuf = new byte[256];
            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = 0x85;
            Array.Copy(header, 0, wBuf, 2, header.Length);
            IIC.WriteRead((uint)(2 + header.Length), wBuf, 0, rBuf);

            k = 1000000;
            while (k-- > 0) ;

            wBuf = new byte[256];
            wBuf[1] = 0xB9;
            IIC.WriteRead(1, wBuf, 14, rBuf);
        }

        private void KeepInBootCmd()
        {
            // 0x01 w 0x01
            byte[] wBuf = new byte[256];
            byte[] rBuf = new byte[256];

            wBuf[0] = I2CConstant.REG_IIC_ADDRESS;
            wBuf[1] = 0x01;
            wBuf[2] = 0x01;
            IIC.WriteRead((uint)3, wBuf, 0, rBuf);
        }

        private byte[] LoadFile(string filePath)
        {
            byte[] data = null;

            BinaryReader br = null;
            FileStream fs = null;

            try
            {
                fs = new FileStream(filePath, FileMode.Open);
                br = new BinaryReader(fs);

                byte[] arr = br.ReadBytes((int)fs.Length);

                string fileExt = Path.GetExtension(filePath);

                if (arr[24] == 'A'
                    && arr[25] == 'W'
                    && arr[26] == '8'
                    && arr[27] == '6'
                    && arr[28] == '8'
                    && arr[29] == '0')
                {
                    int fwLen = arr.Length - 72;
                    // 补足数据长度
                    int lack_arr_len = 128 - (fwLen % 64);

                    data = new byte[fwLen + lack_arr_len];

                    Array.Copy(arr, 72, data, 0, fwLen - 72);

                    for (int i = 0; i < lack_arr_len; i++)
                    {
                        data[fwLen + i] = 0x00;
                    }
                }
                else
                {
                    int fwLen = arr.Length;
                    int lack_arr_len = 128 - (fwLen % 64);
                    data = new byte[fwLen + lack_arr_len];

                    Array.Copy(arr, 0, data, 0, fwLen);

                    for (int i = 0; i < lack_arr_len; i++)
                    {
                        data[fwLen + i] = 0x00;
                    }
                }

                br.Close();
                fs.Close();

                return data;
            }
            catch (Exception e)
            {
                return null;
            }
            finally
            {
                if (null != br)
                {
                    br.Close();
                }
                if (null != fs)
                {
                    fs.Close();
                }
            }
        }

        public static void Sleep(int time)
        {
            if (time <= 0)
            {
                return;
            }
            DateTime start = DateTime.Now;
            while (DateTime.Now.Subtract(start).TotalMilliseconds < time)
            {
            }
        }
    }
}
